package orm

import (
	"hertz_demo/orm/cache"
	"hertz_demo/orm/db"
	"hertz_demo/orm/models"
	"time"
)

func PublishVideo(video *models.Video) error {
	dbVideo := new(db.Video)
	dbVideo.Title = video.Title
	dbVideo.PlayUrl = video.PlayUrl
	dbVideo.CoverUrl = video.CoverUrl
	dbVideo.UserId = video.Author.ID
	err := db.DB.Model(&db.Video{}).Create(dbVideo).Error
	if err == nil {
		createTime := dbVideo.CreatedAt.Unix()
		cache.AddVideo2Feed(dbVideo.ID, createTime)
	}
	return err
}

func GetPublishList(user *models.User) ([]models.Video, error) {
	var resultList []models.Video
	var dbVideoList []db.Video
	if err := db.DB.Model(&db.Video{}).Find(&dbVideoList, "user_id = ?", user.ID).Error; err != nil {
		return resultList, err
	}
	var favouriteList []int64
	if err := db.DB.Model(&db.FavouriteRelation{}).Select("video_id").Where("user_id = ?", user.ID).Scan(&favouriteList).Error; err != nil {
		return resultList, err
	}
	for _, dbVideo := range dbVideoList {
		isFavourite := false
		for _, vid := range favouriteList {
			if vid == dbVideo.ID {
				isFavourite = true
				break
			}
		}
		video := models.Video{
			ID:             dbVideo.ID,
			Author:         *user,
			Title:          dbVideo.Title,
			PlayUrl:        dbVideo.PlayUrl,
			CoverUrl:       dbVideo.CoverUrl,
			FavoriteCount: dbVideo.FavouriteCount,
			CommentCount:   dbVideo.CommentCount,
			IsFavorite:    isFavourite,
		}
		resultList = append(resultList, video)
	}
	return resultList, nil
}

func GetVideoFeed(userId int64, latestTime int64) ([]models.Video, int64, error) {
	var result []models.Video
	videoIdList, err := cache.GetVideoFeed(latestTime)
	if err != nil {
		return result, 0, err
	}
	var dbVideoList []db.Video
	if err := db.DB.Model(&db.Video{}).Find(&dbVideoList, videoIdList).Error; err != nil {
		return result, 0, err
	}
	var userIdList []int64
	for _, dbVideo := range dbVideoList {
		userIdList = append(userIdList, dbVideo.UserId)
	}
	var dbUserList []db.User
	if err := db.DB.Model(&db.User{}).Find(&dbUserList, userIdList).Error; err != nil {
		return result, 0, err
	}
	var followList []int64
	var favouriteList []int64
	if userId != 0 {
		if err := db.DB.Model(&db.FollowRelation{}).Select("follow_user_id").Where("user_id=?", userId).Find(&followList).Error; err != nil {
			return result, 0, err
		}
		if err := db.DB.Model(&db.FavouriteRelation{}).Select("video_id").Where("user_id=?", userId).Find(&followList).Error; err != nil {
			return result, 0, err
		}
		followList = GetIntersection(followList, userIdList)
		favouriteList = GetIntersection(favouriteList, videoIdList)
	}
	nextTime := time.Now().Unix()
	for _, dbVideo := range dbVideoList {
		isFollow := false
		for _, id := range followList {
			if id == dbVideo.UserId {
				isFollow = true
				break
			}
		}
		isFavourite := false
		for _, id := range favouriteList {
			if id == dbVideo.ID {
				isFavourite = true
				break
			}
		}
		videoAuthor := models.User{
			ID:       dbVideo.UserId,
			IsFollow: isFollow,
		}
		for _, dbUser := range dbUserList {
			if dbUser.ID == dbVideo.UserId {
				videoAuthor.Name = dbUser.Name
				videoAuthor.FollowCount = dbUser.FollowCount
				videoAuthor.FollowerCount = dbUser.FollowerCount
				break
			}
		}
		video := models.Video{
			ID:             dbVideo.ID,
			Author:         videoAuthor,
			Title:          dbVideo.Title,
			PlayUrl:        dbVideo.PlayUrl,
			CoverUrl:       dbVideo.CoverUrl,
			FavoriteCount: dbVideo.FavouriteCount,
			CommentCount:   dbVideo.CommentCount,
			IsFavorite:    isFavourite,
		}
		result = append(result, video)

		oldestTime := dbVideo.CreatedAt.Unix()
		if oldestTime < nextTime {
			nextTime = oldestTime
		}
	}
	return result, nextTime, nil
}
